/**
 * <p>Title: Bullet</p>
 * <p>Description: The spaceship has to shot something, uh?</p>
 * @author Guilherme Mauro Germoglio
 */

import java.awt.*;
import javax.swing.*;

public class Bullet
    extends Thread {

  //atributes
  private double x;
  private double y;
  private double x_velocity;
  private double y_velocity;
  private double direction;
  private JPanel panel;
  final int R = 3;
  private boolean hitSomething;
  private boolean paused;

  /**
   * Bullet's constructor... the JPanel
   * @param panel The JPanel
   */
  public Bullet(JPanel panel) {
    this.hitSomething = false;
    this.panel = panel;
    this.paused = false;
  }

  /**
   * Sets the bullet's X coordinate
   * @param x The new X coordinate
   */
  public void set_X(double x) {
    this.x = x;
  }

  /**
   * Sets the bullet's Y coordinate
   * @param y The new Y coordinate
   */
  public void set_Y(double y) {
    this.y = y;
  }

  /**
   * Returns the bullet's X coordinate
   * @return The bullet's X coordinate
   */
  public double get_X() {
    return x;
  }

  /**
   * Returns the bullet's Y coordinate
   * @return The bullet's Y coordinate
   */
  public double get_Y() {
    return y;
  }

  /**
   * Returns the bullet's velocity on the horizontal axis
   * @return The bullet's velocity on the X axis
   */
  public double get_X_velocity() {
    return x_velocity;
  }

  /**
   * Returns the bullet's velocity on the vertical axis
   * @return The bullet's velocity on the Y axis
   */
  public double get_Y_velocity() {
    return y_velocity;
  }

  /**
   * Check if the thread is paused or not
   * @return If the thread is paused or not
   */
  public boolean isPaused() {
    return paused;
  }

  /**
   * Sets the value of paused atribute
   * @param isOrNot If the thread will or won't be paused
   */
  public void setPause(boolean isOrNot) {
    this.paused = isOrNot;
  }

  /**
   * Indicates if the bullet is out of the panel's bounds or not
   * @return true if so, false case not
   */
  public boolean isOutOfBounds() {
    Dimension d = panel.getSize();
    if (get_X() < 0) {
      return true;
    }
    if (get_X() > d.width) {
      return true;
    }
    if (get_Y() < 0) {
      return true;
    }
    if (get_Y() > d.height) {
      return true;
    }
    return false;
  }

  /**
   * Draws the bullet on the panel
   * @return A polygon which is a bullet
   */
  public Polygon drawBullet() {
    Polygon p = new Polygon();
    int x = (int) get_X();
    int y = (int) get_Y();
    for (int k = 0; k < 4; k++) {
      p.addPoint(
          (int) (x + Math.cos(k * 2 * Math.PI / 4)),
          (int) (y + Math.sin(k * 2 * Math.PI / 4))
          );
    }
    return p;
  }

  /**
   * Turns a flying bullet into a dull boring shell without any life
   */
  public void hitTheTarget() {
    this.hitSomething = true;
  }

  /**
   * Checks if the bullet has hit a or not something, like an asteroid
   * @return True if has hit something, false case not
   */
  public boolean hasHitSomething() {
    return hitSomething;
  }

  /**
   * Starts the bullet's thread
       * @param x The X coordinate (where in the horizontal axis the bullet will start)
       * @param y The Y coordinate (where in the vertical axis the bullet will start)
   * @param direction It's trajetory angle
   */
  public void start(double x, double y, double direction) {
    this.x = x;
    this.y = y;
    this.direction = direction;
    this.x_velocity = 5 * Math.cos(direction * Math.PI / 180);
    this.y_velocity = 5 * Math.sin(direction * Math.PI / 180);
    super.start();
  }

  /**
   * Coordinates the bullet's movement
   */
  public void move() {
    Graphics g = panel.getGraphics();
    Polygon p = new Polygon();
    if (!paused) {
      set_X( (get_X() + get_X_velocity()));
      set_Y( (get_Y() + get_Y_velocity()));
    }
    showBullet(g, Color.BLACK);
  }

  /**
   * Shows the bullet in the window
   * @param graphic The graphic which will "draw" the bullet
   * @param color The bullet's collor
   */
  private void showBullet(Graphics graphic, Color color) {
    Polygon bullet = drawBullet();
    graphic.setColor(color);
    graphic.drawPolygon(bullet);
    try {
      Thread.sleep(10);
    }
    catch (InterruptedException e) {}
    graphic.setColor(panel.getBackground());
    graphic.drawPolygon(bullet);
    graphic.dispose();

  }

  /**
   * Runs the thread, i think
   */
  public void run() {
    try {
      while (!isOutOfBounds() && !hasHitSomething()) {
        move();
        Thread.sleep(1);
      }
    }
    catch (InterruptedException e) {}
  }
}